
#include <BFont>
#include <BStyle>
#include <BWidget>
#include <BMenuBar>

#include "IAlignment.h"
#include "member_BMenuBar.h"
#include "member_BMenu.h"
#include "member_BWidget.h"

using namespace BWE;

void MenuBarItem::dispenseStyles(const BStyle* style)
{
	if (menu)
	{
		if (widget_member(menu)->dirtyStyle)
			menu->flush();
		BIcon* icon = 0;
		if (menu->name().size())
			icon = style->icon(menu->name());
		if (!icon)
			icon = style->icon(menu->title());
		if (icon)
			menu->setIcon(icon);
	}
	color.reset();
	graph = Graph_None;
	image = 0;
	icon = 0;
	text.clear();
	if (menu)
	{
		icon = menu->icon();
		text = menu->title();
	}
	IAlignItem::dispenseStyles(style);
}
void MenuBarItem::translateText(const BStyle* style)
{
	if (menu)
	{
		block.text = widget_member(menu)->t_title;
	}
}

member_BMenuBar::member_BMenuBar(BMenuBar* menuBar)
{
	boss = menuBar;
	orientation = Orientation_Horizontal;
	align = Align_LeftCenter;
	form = Form_None;
	spacing = 1;
	separatorSize = 1;
	separatorStyle = 0;
	hoverIndex = -1;
	pressed = false;
	dirty = false;
}
member_BMenuBar::~member_BMenuBar()
{

}

void member_BMenuBar::freshRects()
{
	const BStyle* style = boss->realStyle();
	const BFont* font = boss->realFont();

	for (int i = 0; i < items.size(); i++)
	{
		MenuBarItem& item = items[i];
		if (item.dirtyStyle)
		{
			item.form = form;
			item.align = align;
			item.spacing = spacing;
			item.dispenseStyles(style);
			item.applyStyle(style);
			item.dirtyStyle = false;
			item.dirty = true;
		}
		if (item.dirty)
		{
			item.freshSize(font, 0);
			item.dirty = false;
		}
	}

	BRect crect = boss->centerRect();
	int width = 0;
	int height = 0;
	contentSize.reset();
	if (orientation == Orientation_Vertical)
	{
		for (int i = 0; i < items.size(); i++)
		{
			MenuBarItem& item = items[i];
			if (item.menu == 0)
			{
				item.hintSize = separatorSize;
			}
			else if (item.dirty)
			{
				item.freshSize(font, 0);
				item.dirty = false;
			}
			width = bMax(width, item.hintSize.width() + spacing);
			height += item.hintSize.height() + spacing;
		}
		height -= spacing;
		int posX = crect.x();
		int posY = crect.y();
		for (int i = 0; i < items.size(); i++)
		{
			MenuBarItem& item = items[i];
			item.pos.set(posX, posY);
			item.setSize(crect.width(), item.hintSize.height());
			BRect arrowArea = item.rect();
			arrowArea.left() = item.rect().right();
			posY += item.hintSize.height() + spacing;
		}
	}
	if (orientation == Orientation_Horizontal)
	{
		for (int i = 0; i < items.size(); i++)
		{
			MenuBarItem& item = items[i];
			if (item.menu == 0)
			{
				item.hintSize = separatorSize;
			}
			else if (item.dirty)
			{
				item.freshSize(font, 0);
				item.dirty = false;
			}
			height = bMax(height, item.hintSize.height());
			width += item.hintSize.width() + spacing;
		}
		width -= spacing;
		int posX = crect.x();
		int posY = crect.y();
		for (int i = 0; i < items.size(); i++)
		{
			MenuBarItem& item = items[i];
			item.pos.set(posX, posY);
			item.setSize(item.hintSize.width(), crect.height());
			BRect arrowArea = item.rect();
			arrowArea.left() = item.rect().right();
			posX += item.hintSize.width() + spacing;
		}
	}
	contentSize.set(width, height);
}

void member_BMenuBar::slotMenuEnabled(BObject* object, const BValue& value)
{
	boss->fresh();
}
void member_BMenuBar::slotMenuRenamed(BObject* object, const BValue& value)
{
	for (int i = 0; i < items.size(); i++)
	{
		if (items[i].menu == object)
		{
			dirty = true;
			items[i].dirty = true;
			boss->fresh();
			break;
		}
	}
}
void member_BMenuBar::slotMenuStyled(BObject* object, const BValue& value)
{
	for (int i = 0; i < items.size(); i++)
	{
		if (items[i].menu == object)
		{
			dirty = true;
			items[i].dirty = true;
			boss->fresh();
			break;
		}
	}
}
void member_BMenuBar::slotMenuIconChanged(BObject* object, const BValue& value)
{
	BMenu* menu = (BMenu*)object;
	for (int i = 0; i < items.size(); i++)
	{
		MenuBarItem& item = items[i];
		if (item.menu == menu)
		{
			item.dirty = true;
			dirty = true;
			boss->fresh();
			break;
		}
	}
}
void member_BMenuBar::slotMenuTitleChanged(BObject* object, const BValue& value)
{
	BMenu* menu = (BMenu*)object;
	for (int i = 0; i < items.size(); i++)
	{
		MenuBarItem& item = items[i];
		if (item.menu == menu)
		{
			item.dirty = true;
			dirty = true;
			boss->fresh();
			break;
		}
	}
}
